#include <iostream>
#include <cstdlib>
#include <ctime>
#include "BlockQueue.hpp"
#include "task.hpp"

using namespace std;
char chs[4] = {'+', '-', '*', '/'};

void *runProducer(void *arg)
{
    yui::BlockQueue<Task<int>> *bq = static_cast<yui::BlockQueue<Task<int>> *>(arg);
    while (true)
    {
        sleep(1);
        int a = rand() % 100;
        int b = rand() % 100;
        char c = chs[rand() % 4];
        bq->push(Task<int>(a, b, c));
        cout << "生产者生产了一个问题:" << a << c << b << "= ?" << endl;
        cout << "--------------------------" << endl;
    }
    pthread_exit((void *)0); // 退出线程
}

void *runConsumer(void *arg)
{
    yui::BlockQueue<Task<int>> *bq = static_cast<yui::BlockQueue<Task<int>> *>(arg);
    while (true)
    {
        // sleep(1);
        Task<int> *tmp = new Task<int>;
        bq->pop(tmp);
        int ret = 0;
        if (tmp->calculator(ret) == 0)
        {
            cout << "消费者解决问题得:" << tmp->_a << tmp->_ch << tmp->_b << " = " << ret << endl;
            cout << "--------------------------" << endl;
        }
        else if (tmp->calculator(ret) == ZERODIVERROR)
        {
            cout << "问题存在错误:" << tmp->_a << tmp->_ch << tmp->_b << " = ?" << "存在除0错误" << endl;
            cout << "--------------------------" << endl;
        }
        else if (tmp->calculator(ret) == CHARERROR)
        {
            cout << "问题存在错误:" << tmp->_a << tmp->_ch << tmp->_b << " = ?" << "存在未定义字符："<<tmp->_ch<< endl;
            cout << "--------------------------" << endl;
        }
    }
    pthread_exit((void *)0); // 退出线程
}

int main()
{
    srand((unsigned int)time(nullptr));
    yui::BlockQueue<Task<int>> *bq = new yui::BlockQueue<Task<int>>(5); // 创建阻塞队列
    // 创建生产消费者线程
    pthread_t producer;
    pthread_t consumer;
    if (pthread_create(&producer, nullptr, runProducer, bq) < 0)
    {
        perror("线程创建失败");
        return 1;
    }
    if (pthread_create(&consumer, nullptr, runConsumer, bq) < 0)
    {
        perror("线程创建失败");
        return 1;
    }
    if (pthread_join(producer, nullptr) < 0)
    {
        perror("线程回收失败！");
        return 1;
    }
    if (pthread_join(consumer, nullptr) < 0)
    {
        perror("线程回收失败！");
        return 1;
    }
    delete bq;
    return 0;
}